/**
 * Created by hjqi on 2016/1/13.
 */
var jwt = require('jsonwebtoken');
var express = require('express');
var router = express.Router();
var userBasicInfoCol = require('../lib/config/config').config.mongodb.userBasicInfo_collection;
var UserBasicInfoDB = require('../db/userBasicInfoDB');
var config = require('../lib/config/config').config;
var __db = new UserBasicInfoDB(userBasicInfoCol);
var MongoDB = require('../db/mongodb');
var identifyingCode_collection_name = require('../lib/config/config').config.mongodb.identifyingCode_collection;
var identifyingCodeDB = new MongoDB(identifyingCode_collection_name);

var libUser = require('../lib/user/user');
var _user = new libUser();
var _k8s_adp = require('../lib/k8s/k8sAdpter');
var logger = require('../lib/log4js/log4js').logger('userBasicInfo');
var libCluster = require('../lib/cluster/cluster');
var _lib_cluster = new libCluster();


router.get('/isExists', function (req, res, next) {

        var db = req.db;
        var param = req.query;
        var queryData = {};
        if (param.user)
            queryData.username = param.user;
        if (param.phone)
            queryData.phoneNumber = param.phone;
        //queryData = "{'username': '" + param.user + "'}";
        __db.exists(db, queryData, cb);

        function cb(err, one) {
            if (err)
                res.send(err);
            else {
                /*if (one.length != 0)
                    res.send(true);
                else
                    res.send(false);*/
                res.send(one);
            }
        }


});
if(!config.disableIndentifyingCode) {
    TopClient = require('../lib/topClient/topClient').TopClient;
    var appKey = "23399266";
    var secret = '4ba32296baadccf98768832e7b9a0760';
    var client = new TopClient({
        'appkey': appKey,
        'appsecret': secret,
        'REST_URL': 'http://gw.api.taobao.com/router/rest'
    });
    var smsTemplateCode = 'SMS_11570117';
    var signName = '自然云';
}
var pad = require('pad');

router.get('/triggerIdentifyingCode', function (req, res, next) {
    logger.info("start triggerIdentifyingCode，disable identifyingcode＝"+config.disableVerifyingCode);
    var db = req.db;
    var param = req.query;
    var phoneNumber = param.phone;

    var queryData = {
        phoneNumber:phoneNumber
    };
    //判断手机号是否正确 modified by Michael
    var reg = /^(13[0-9]|14[0-9]|15[0-9]|18[0-9])\d{8}$/;
    __db.getWithParam(null, queryData, function(err, phoneDocs){
        if (phoneDocs && phoneDocs.length > 0) {
            res.status(400);
            res.send("手机号码" + phoneNumber + " 已经注册过！");
        }else if(!reg.test(phoneNumber)){
            res.status(400);
            res.send("请输入正确的手机号！");
        }

        else {
            var code = Math.ceil(Math.random()*(9999-1)+1);
            code = pad(4, code, "0");

            var query = {
                "phoneNumber": phoneNumber,
            }
            var doc = {
                "createdAt": new Date(),
                "phoneNumber": phoneNumber,
                "identifyingCode": code
            }

            identifyingCodeDB.updateWithParam(null, query, doc, function (err) {
                if (err) {
                    res.status(400);
                    res.send(err);
                    logger.error("phoneNumber:" + phoneNumber + ". " + err);
                } else {
                    var disableIndentifyingCode=config.disableVerifyingCode;//Dave 加入开关控制20170218
                    logger.info("disable identifyingcode ＝"+disableIndentifyingCode);
                    if(!disableIndentifyingCode) {
                        var maxRetryNum = 3;
                        var isSuccessful = false;
                        var getCode = function (tryNum) {
                            /*var client = new TopClient({
                             'appkey': appKey,
                             'appsecret': secret,
                             'REST_URL': 'http://gw.api.taobao.com/router/rest'
                             });*/
                            client.execute('alibaba.aliqin.fc.sms.num.send', {
                                'sms_type': 'normal',
                                'sms_free_sign_name': signName,
                                'sms_param': {
                                    'code': code
                                },
                                'rec_num': phoneNumber,
                                'sms_template_code': smsTemplateCode
                            }, function (error, response) {
                                if (!error) {
                                    res.send(true);
                                    logger.info("tryNum:" + tryNum + ", phoneNumber:" + phoneNumber + ". " + response);
                                } else {
                                    logger.error("tryNum:" + tryNum + ", phoneNumber:" + phoneNumber + ". " + error);
                                    if (tryNum >= maxRetryNum) {
                                        res.status(400);
                                        res.send(error);
                                    } else {
                                        setTimeout(function () {
                                            getCode(tryNum + 1);
                                        }, 6000);
                                    }
                                }
                            })
                        }
                        getCode(1);
                    }else{
                        res.send({code:code});
                    }
                }
            });
        }
    });
});

//Added by Michael
router.get('/getIdentifyingCode', function (req, res, next) {
    var db = req.db;
    var param = req.query;
    var phoneNumber = param.phone;

    var queryData = {
        phoneNumber:phoneNumber
    };
    //判断手机号是否正确 modified by Michael
    var reg = /^(13[0-9]|14[0-9]|15[0-9]|18[0-9])\d{8}$/;
    __db.getWithParam(null, queryData, function(err, phoneDocs){

        if(!reg.test(phoneNumber)){
            res.status(400);
            res.send("请输入正确的手机号！");
        }

        else if (phoneDocs && phoneDocs.length == 0){
            res.status(400);
            res.send("请输入账号绑定的手机号！");
        }
        else{
            var code = Math.ceil(Math.random()*(9999-1)+1);
            code = pad(4, code, "0");

            var disableIndentifyingCode=config.disableVerifyingCode;//Dave 加入开关控制20170218

            if(!disableIndentifyingCode) {

                var query = {
                    "phoneNumber": phoneNumber,
                };
                var doc = {
                    "createdAt": new Date(),
                    "phoneNumber": phoneNumber,
                    "identifyingCode": code
                };

                identifyingCodeDB.updateWithParam(null, query, doc, function (err) {
                    if (err) {
                        res.status(400);
                        res.send(err);
                        logger.error("phoneNumber:" + phoneNumber + ". " + err);
                    } else {
                        client.execute('alibaba.aliqin.fc.sms.num.send', {
                            'sms_type': 'normal',
                            'sms_free_sign_name': signName,
                            'sms_param': {
                                'code': code
                            },
                            'rec_num': phoneNumber,
                            'sms_template_code': smsTemplateCode
                        }, function (error, response) {
                            if (!error) {
                                res.send(true);
                                logger.info("phoneNumber:" + phoneNumber + ". " + response);
                            } else {
                                res.status(400);
                                res.send(error);
                                logger.error("phoneNumber:" + phoneNumber + ". " + error);
                            }
                        })
                    }
                });
            }
            else{
                res.send(code);
            }
        }
    });
});

/**
 * 用户登录
 */
router.post('/authenticate', function (req, res, next) {
    var db = req.db;
    var authData = req.body;

    //update pullSecr for old user
    if(authData['pullSecr'] !== undefined){
        var _secr = authData['pullSecr'];
        delete  authData['pullSecr'];
        //authData['pullSecr'] = undefined;

        __db.updateField(db,authData,{'pullSecr':_secr},function(err,one){
            if(err){
                logger.error('update pull secrect error:',JSON.stringify(err));
            }else{
                __db.exists(db, authData, cb);
            }
        });
    }else{
        __db.exists(db, authData, cb); //用户名密码匹配验证
    }
    //用户登录验证，因此目前平台采用短信验证所以没有采用密码验证，无论密码是否匹配都可以登录？
    function cb(err, one) {
        if (err)
            res.send(err);
        else {
            var result = {
                authenticated: false
            };
            //logger.debug("authentication:" +JSON.stringify( one )) ;
            if (one.length != 0) {
                var result = {
                    authenticated: true,
                    role: one[0].role
                }
                // Temporarily, Just for trigger user to complete userinfo.
                if (one[0].phoneNumber)
                    result.hasPhone = true;

                //for extend field
                if (one[0].info)
                    result.info = one[0].info;

                result.username = authData.username;
                result.secret = one[0].pullSecr;
                result.exp = Math.floor(Date.now() / 1000) + 3600*24*7;
                var token = jwt.sign(result,"we are the biggest secret");
                if(result.authenticated === true) {
                    res.cookie("token", token, {maxAge: 3600 * 24 * 7 * 1000});
                    res.cookie("username", authData.username, {maxAge: 3600 * 24 * 7 * 1000});
                    createAuthInfoIfAbsent( one[0] ) ;
                }
                res.send(token);
            }else{
                var result = {
                    authenticated: false
                }
                var token = jwt.sign(result,"we are the biggest secret");
                res.send(token);
            }
        }
    }
});

router.post('/insert', function (req, res, next) {
    var db = req.db;
    var data = req.body;
    __db.insert(db, data, cb);

    function cb(err) {
        if (err)
            res.send(err.message);
        else
            res.send("true");
    }
});

var systemUsers = require('../lib/config/config').config.systemusers;
function isSystemUser(user) {
    if (systemUsers.indexOf(user) >= 0)
        return true;
    return false;
}
/**
 * 用户注册 ，TODO registry V2 用户信息以及
 * @RequestMapping("/userBasicInfo/createUser")
 */
router.post('/createUser',function(req, res, next){
    var userInfo =  req.body;
    if (!userInfo.company) {
        res.status(400);
        res.send("请输入公司名");
        return;
    }

    var queryUnique = {
        username: userInfo.username
    }
    __db.getWithParam(null, queryUnique, function(err,userInDB){
        if(err){
            if( !err.message ){
                err = {
                    "message":"unknow error of mongo"
                }
            }
            var error = {
                "message": err.message,
                "username":userInfo.username
            } ;
            logger.error( JSON.stringify( error ) ) ;
            res.status(400);
            //500 mean internal server has some error.do not expose the real error to user(they don't know the meanings)
            res.send("Code:500,用户创建失败!");
            return;
        }
        if (userInDB && userInDB.length > 0) {
            res.status(400);
            res.send("用户名已经存在");
            return;
        } else {
            if (isSystemUser(userInfo.username)) {

                _user.createUser(userInfo).then(function (ret) {
                    res.send(ret);
                }).catch(function (e) {
                    res.status(400);
                    res.send(e);
                });
            } else {
                var phoneNumber = userInfo.phoneNumber;
                var query = {
                    phoneNumber: phoneNumber
                };
                try{
                    identifyingCodeDB.getWithParam(null, query, function (err, docs) {
                        if (docs && docs.length > 0) {
                            var code = docs[0].identifyingCode;
                            var disableIndentifyingCode=config.disableVerifyingCode;//Dave 加入开关控制20170218
                            if (code == userInfo.identifyingCode||disableIndentifyingCode) {//一旦关闭，不再验证
                                _user.createUser(userInfo).then(function (ret) {
                                    var result = {
                                        username:userInfo.username,
                                        hasPhone:true
                                    };

                                    var token = jwt.sign(result,"we are the biggest secret");
                                    res.cookie("token",token,{maxAge:3600*24*7*1000});
                                    res.cookie("username",result.username,{maxAge:3600*24*7*1000});
                                    res.cookie("hasPhone",result.hasPhone?1:0,{maxAge:3600*24*7*1000});

                                    res.send(ret);
                                }).catch(function (e) {
                                    logger.error("[createUser Fail]"+JSON.stringify(e) ) ;
                                    res.status(400);
                                    res.send(e);
                                });
                            } else {
                                res.status(400);
                                res.send("请输入正确的验证码");
                            }
                        } else {
                            res.status(400);
                            res.send("验证码已经失效");
                        }
                    });
                }catch(e){
                    logger.error("[identifyingCodeDB]"+JSON.stringify( e ) )
                }
            }
        } //-fi
    });

});

router.post('/updateUser',function(req, res, next){
    var userInfo =  req.body;
    if (!userInfo.company) {
        res.status(400);
        res.send("请输入公司名");
        return;
    }

    var phoneNumber = userInfo.phoneNumber;
    var query = {
        phoneNumber: phoneNumber
    };
    identifyingCodeDB.getWithParam(null, query, function(err,docs){
        if (docs && docs.length > 0) {
            var code = docs[0].identifyingCode;
            if (code == userInfo.identifyingCode) {
                var username =  req.username;
                var userQuery = {
                    username: username
                };
                delete userInfo.identifyingCode;
                var updateFields = {
                    $set: userInfo
                };
                __db.updateWithParam(null, userQuery, updateFields, function (err) {
                    if (err) {
                        res.status(400);
                        res.send(err);
                        logger.error("更新用户" + username + "出错：" + err);
                    } else {
                        updateAuth( userInfo ) ;
                        res.send(true);
                    }
                });
            } else {
                res.status(400);
                res.send("请输入正确的验证码");
            }
        } else {
            res.status(400);
            res.send("验证码已经失效");
        }
    });
});
/**
 * 更新用户认证信息
 */
function updateAuth(userInfo){
    //只有密码更改的时候才会更新用户的认证信息，否则没必要
    if( userInfo && userInfo.password ){
        _user.updateAuthInfo( userInfo).then(function () {
            logger.debug( "[#updateAuth] authentication updated successfully")

        }).catch(function ( err ) {
            logger.error( "[#updateAuth] exception occurred when update the authentication info" ,err)
        }) ;
    }
}

/**
 * 重置密码：
 * 1、更新数据库
 * 2、更新k8s
 * Added by Michael
 */
router.post('/resetPwd',function(req, res, next){
    var userInfo =  req.body;
    var queryUnique = {
        username: userInfo.username
    };
    __db.getWithParam(null, queryUnique, function(err,userInDB){
        var phoneNumber = userInfo.phoneNumber;
        var query = {
            phoneNumber: phoneNumber
        };
        identifyingCodeDB.getWithParam(null, query, function(err,docs){
            if (docs && docs.length > 0) {
                var code = docs[0].identifyingCode;
                var userQuery = {
                    username: userInfo.username
                };

                var updateFields = {
                    $set: userInfo
                };
                var disableIndentifyingCode=config.disableVerifyingCode;

                if (code == userInfo.identifyingCode || disableIndentifyingCode) {
                    __db.updateWithParam(null, userQuery, updateFields, function (err) {
                        if (err) {
                            res.status(400);
                            res.send(err);
                            logger.error("更新用户" + username + "出错：" + err);
                        } else {
                            updateSecretInAllClusters( userInfo.username, userInfo) ;
                            updateAuth( userInfo ) ;
                            res.status(200);
                            res.send(true);
                        }
                    })
                } else {
                    res.status(400);
                    res.send("请输入正确的验证码");
                }
            } else {
                res.status(400);
                res.send("验证码已经失效");
            }
        });

    });
});

//Added by Michael
router.get('/getUserInfo', function (req, res, next) {
    var db = req.db;
    var param = req.query;
    var queryData = {};
    if (param.user)
        queryData.username = param.user;
    if (param.phone)
        queryData.phoneNumber = param.phone;
    //queryData = "{'username': '" + param.user + "'}";
    __db.exists(db, queryData, cb);

    function cb(err, one) {
        if (err)
            res.send(err);
        else {
            if (one.length != 0)
                res.send(one[0].phoneNumber);
            else
                res.send("");
        }
    }
});
/**
 * update the secret of all clusters asynchronously  under the namespace
 */
function updateSecretInAllClusters(ns,userInfo) {
    var clusers=[] ;

    _lib_cluster.getClusters(ns).then(function( ret ){
        clusers = ret ;
        if(!clusers || clusers.length == 0 ){
            clusers = [];
        }
        clusers.push({
            "clusterId":undefined,
            "flag":"default cluster"
        }) ;//add default cluster

        clusers.forEach(function(clusterId){
            if( clusterId.clusterId ){
                //更新Api-server中secret数据
                _k8s_adp.getK8s(clusterId.clusterId).then(function(_k8s){
                    var secret = userInfo.pullSecr ;
                    return _k8s.patchPullImageSecret(userInfo.username,secret) ;
                }).then(function(ret){
                    if( ret ){
                        logger.debug( "getClusters#setSecret->"+JSON.stringify( ret ) ) ;
                    }
                    logger.info( (!clusterId.clusterId?"default":clusterId.clusterId)+" add secret success[async]") ;
                }).catch(function (err) {
                    logger.error( clusterId.clusterId+" patch secret failed![async] "+JSON.stringify( err )) ;
                });
            }
        }) ;
    }).catch(function ( err ) {
        logger.error("Can't get clusterInfo ,"+JSON.stringify( err ))
    });

}
/**
 * 假如该用户未创建认证信息，就创建一下，正常情况下应该是注册用户的时候就会创建的
 */
function createAuthInfoIfAbsent(userinfo){
    var username = userinfo.username ;
    var pass = userinfo.password ;

    _user.existAuthInfo(username).then(function(isExist) {
        if(!isExist){
            _user.insertAuthInfo( userinfo);
        }
    }).catch(function (err) {
        logger("创建认证信息失败！"+JSON.stringify( err )) ;
    }) ;
}

module.exports = router;